#pragma once

#ifndef _FRAME_WORK_H_ 
#define _FRAME_WORK_H_

#include "base_type.h"
#include "as_address.h"
#include "as_callback.h"
#include "mailpos.h"
#include <memory>
#include <mutex>

class ThreadPool;
namespace as
{

namespace net
{
class TcpServer;
class EpollWatch;
}

namespace md
{
typedef std::shared_ptr<as::net::Address> AddressPtr;
struct FrameWorkConfig
{
	int id_ = 0;
	int thread_count_ = 1;
	const char *name_ = nullptr;
	AddressPtr addr_ = nullptr;
};

class Actor;
class NetManager;
class MailBoxCenter;
class FrameWork 
{
public:
	FrameWork(const FrameWorkConfig &cnf);
	~FrameWork();

	void Start();
	void Loop();
	void Stop();

	void RegisterActor(Actor *actor);
	void UnregisterActor(Actor *actor);

	void Process();

	uint32 GetPriKey() { return pri_key_; };

public:
	void Send(ByteBufferPtr &buf, const MailPos &sender, const MailPos &recipient);
	void Send(ByteBufferPtr &buf, const MailPos &sender, const char *recipientName, int pri_key = 0);
	void SendAll(ByteBufferPtr &buf, const MailPos &sender);
	void HandleRemoteMsgByAddr(MailPos &from, MailPos &to, ByteBufferPtr buf);
	void HandleRemoteMsgByName(MailPos &from, const std::string &to, ByteBufferPtr buf);
public:
	void SetPeerAddr(as::net::Address &addr);
	void AddRemoteEndPoint(as::net::Address &addr);

private:
	const char *name_ = nullptr;
	std::shared_ptr<as::net::EpollWatch> ep_;
	std::shared_ptr<NetManager> net_manager_;
	std::shared_ptr<MailBoxCenter> center_;
	std::unique_ptr<ThreadPool> thread_pool_;
	std::mutex lock_;
	const uint32 pri_key_;
	std::atomic_bool isStop = false;
};

}
}

#endif